# coding=utf8
from pyjvm.classfile.clstype import *
from pyjvm.exceptions import ClassByteReadError
from typing import List


class ClassBytesReader:
    """
    用于类文件字节码读取
    """

    def __init__(self, class_bytes: bytes, index=0):
        self.__cls_bytes = class_bytes
        self.__index = index
        self.__length = len(class_bytes)

    def read(self, length: int) -> bytes:
        """
        按byte读取字节码
        args:
            length：要读取的byte数
        """
        end = self.__index + length
        if end > self.__length:
            raise ClassByteReadError('没有足够的字节码读取')
        _bytes = self.__cls_bytes[self.__index: end]
        self.__index = end
        return _bytes

    def u1(self) -> u1:
        return self.read(1)

    def u2(self) -> u2:
        return self.read(2)

    def u2s(self) -> List[u2]:
        return [self.u2() for _ in range(self.int16())]

    def u4(self) -> u4:
        return self.read(4)

    def int8(self) -> int:
        return int8(self.u1())

    def uint8(self) -> int:
        return uint8(self.u1())

    def char(self) -> str:
        return char(self.u1())

    def int16(self) -> int:
        return int16(self.u2())

    def uint16(self) -> int:
        return uint16(self.u2())

    def int32(self) -> int:
        return int32(self.u4())

    def int16s(self) -> list:
        length = self.int16()
        return [self.int16() for _ in range(length)]

    def int32s(self, length: int) -> list:
        return [self.int32() for _ in range(length)]

    def float(self) -> float:
        return float0(self.u4())

    def long(self) -> int:
        return uint64(self.read(8))

    def double(self) -> float:
        return double(self.read(8))

    def utf8(self) -> str:
        length = self.uint16()
        return self.utf8_of(length)

    def utf8_of(self, length) -> str:
        return utf8(self.read(length))

    def reset(self, class_bytes: bytes, index: int):
        if class_bytes is not None:
            self.__cls_bytes = class_bytes
        self.__index = index
        self.__length = len(class_bytes)

    def pc(self):
        return self.__index

    def readable(self):
        return self.__index < self.__length


__all__ = ['ClassBytesReader']
